﻿#include "browsermainwindow.h"
#include "ui_browsermainwindow.h"

#include <QDebug>
#include <QPainter>

#pragma execution_character_set("utf-8")

BrowserMainWindow::BrowserMainWindow(Browser *browser, QWidget *parent, QWebEngineProfile *profile) :
    QWidget(parent),
    ui(new Ui::BrowserMainWindow)
{
    ui->setupUi(this);
    if(profile == nullptr){
        profile = QWebEngineProfile::defaultProfile();
    }
    // 初始化窗口参数
    setWindowFlags(Qt::FramelessWindowHint);
    setWindowTitle("safe browser(作者：栢晓笙)");
    setWindowIcon(QIcon(QStringLiteral(":/app_resource/logo.png")));
    ConfigManager &configManager = ConfigManager::getInstance();
    resize(configManager.getDefaultWindowWidth(), configManager.getDefaultWindowHeight());
    currentTheme = ThemeManager::getInstance().getCurrentTheme();
    this->counter = 0;

    // 初始化标签栏参数
    this->ui->tab_bar->setProfile(profile);
    connect(this->ui->tab_bar, &TabBarWidget::changeView, this, &BrowserMainWindow::changeWebView);
    connect(this->ui->tab_bar, &TabBarWidget::removeView, this, &BrowserMainWindow::removeTab);

    // 初始化菜单
    settingMenu = new SettingMenu(this);
    settingMenu->setStyleSheet("background-color: rgb(40, 29, 78);");
    settingMenu->hide();

    // 初始化菜单事件
    connect(this->ui->menu_bar, &MenuBarWidget::showOrHideSetting, this, [=]{
       if(settingMenu->isHidden()){
           settingMenu->show();
       } else{
           settingMenu->hide();
       }
    });
    connect(this->ui->menu_bar, &MenuBarWidget::showDownloadWindow, this, [=]{
        // 打开下载管理器
       emit showDownloadWindow();
    });

    // 主题设置窗口
    themeWindow = new ThemeWindow(this);
    themeWindow->hide();
    connect(this->ui->menu_bar, &MenuBarWidget::showThemeWindow, this, [=](){
       // 打开主题管理器
        if(themeWindow->isHidden()){
            themeWindow->show();
        }else{
            themeWindow->hide();
        }
    });
    // 更新主题切换
    connect(themeWindow, &ThemeWindow::changeTheme, [=](Theme theme){
        currentTheme = theme;
        update();         // 窗口重绘
    });

    // 初始化密码管理器窗口（密码管理器界面单例模式实现，直接获取不需要每个窗口单独管理）
    passwordMangerWindow = new PasswordManagerWindow(this);
    passwordMangerWindow->hide();
    connect(settingMenu, &SettingMenu::showPasswordManager, this, [=]{
        if(passwordMangerWindow->isHidden()){
            passwordMangerWindow->show();
        }else{
            passwordMangerWindow->hide();
        }
    });

    // 打开插件管理器窗口
    connect(settingMenu, &SettingMenu::showPluginManagerWindow, this, &BrowserMainWindow::showPluginManagerWindow);

    // 打开设置窗口
    configWindow = new ConfigWindow(this);
    configWindow->profile = profile;
    configWindow->hide();
    connect(settingMenu, &SettingMenu::showConfigWindow, this, [=](){
        if(configWindow->isHidden()){
            configWindow->show();
        }else{
            configWindow->hide();
        }
    });

    // 初始化书签窗口界面
    favoriteManagerWindow = new FavoriteManagerWindow(this);

    favoriteManagerWindow->hide();
    connect(settingMenu, &SettingMenu::showFaviroteWindow, this, [=]{
        if(favoriteManagerWindow->isHidden()){
            favoriteManagerWindow->show();
        }else{
            favoriteManagerWindow->hide();
        }
    });
    favoriteManagerWindow->updateWindow();

    // 初始化历史记录管理器窗口
    historyManagerWindow = new HistoryManagerWindow(this);

    historyManagerWindow->hide();
    connect(settingMenu, &SettingMenu::showHistoryWindow, this, [=]{
        if(historyManagerWindow->isHidden()){
            historyManagerWindow->show();
            historyManagerWindow->updateWindow();      // 重新加载窗口数据
        }else{
            historyManagerWindow->hide();
        }
    });
    historyManagerWindow->updateWindow();

    // 初始化状态栏(显示在内容区域)
    stausBarWidget = new StatusBarWidget(this);

    // 搜索框
    pageSearchWindow = new PageSearchWindow(this);
    pageSearchWindow->hide();
    connect(this->ui->menu_bar, &MenuBarWidget::showPageSearchWindow, this, [=](){
       // 打开主题管理器
        if(pageSearchWindow->isHidden()){
            pageSearchWindow->show();
        }else{
            pageSearchWindow->hide();
        }
    });
    connect(pageSearchWindow, &PageSearchWindow::search, [=](QString subString){
        // 页面搜索
        TabBarButton *tabBarButton  = tabWidget()->currentTab;
        if(tabBarButton == nullptr)return;
        tabBarButton->view_widget->findText(subString);
    });

    // 其他相关的事件监听
    connect(tabWidget(), &TabBarWidget::changeUrl, this, &BrowserMainWindow::changeInputUrl);   // url改变时的监听
    connect(tabWidget(), &TabBarWidget::linkHover, this, &BrowserMainWindow::handleLinkHover);


}

BrowserMainWindow::~BrowserMainWindow()
{
    delete ui;
}

TabBarWidget *BrowserMainWindow::tabWidget()
{
    return this->ui->tab_bar;
}

void BrowserMainWindow::changeWebView(TabBarButton *ptr)
{
    qDebug() << "main: change web view" << ptr << "url: " << ptr->view_widget->url();
    this->ui->content->changeWebView(ptr->view_widget);
}

void BrowserMainWindow::removeTab(TabBarButton *ptr)
{
    this->ui->content->removeView(ptr);
}

void BrowserMainWindow::changeInputUrl(QString url)
{
    // 更新url输入框
    this->ui->tool_bar->setUrl(url);
}

void BrowserMainWindow::handleLinkHover(const QString &url)
{
    qDebug() << "handleLinkHover : " << url;
    this->stausBarWidget->showText(url);
}

void BrowserMainWindow::handleShowDownloadWindow()
{
    //    browser->downloadWindow->show();
}

void BrowserMainWindow::showPluginManagerWindow()
{
    pluginManagerWindow->show();
    pluginManagerWindow->activateWindow();
}

void BrowserMainWindow::addFavirote(UrlInfo urlInfo)
{
    this->favoriteManagerWindow->addFavoriteUrlLink(urlInfo);
}

void BrowserMainWindow::repaint(int x, int y, int w, int h)
{
    qDebug() << "main window repaint: " << w << ", " << h << Qt::endl;
}

/**
 * 重绘背景
 */
void BrowserMainWindow::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.drawPixmap(rect(), QPixmap(currentTheme.backgroundPath), QRect());

    // 移动状态栏位置
    ContentWidget * contentWidget = this->ui->content;
    int targetPosY = contentWidget->pos().y() + contentWidget->height() - this->stausBarWidget->height();
    int targetPosX = contentWidget->pos().x();
//    qDebug() << targetPosX <<targetPosY;
    int h = this->stausBarWidget->height();
    this->stausBarWidget->resize(width(), h);
    this->stausBarWidget->move(targetPosX, targetPosY);
}

// 处理边框拖动缩放(这种方法需要依赖windows,在linux上实际会不兼容，后续更改)
bool BrowserMainWindow::nativeEvent(const QByteArray &eventType, void *message, qintptr *result)
{
    MSG* msg = (MSG*)message;
    switch(msg->message)
        {
        case WM_NCHITTEST:
            {
                long x = GET_X_LPARAM(msg->lParam);
                long y = GET_Y_LPARAM(msg->lParam);
//                long window_x = pos().x();
//                long window_y = pos().y();   // qt6中这个似乎得到是错误的坐标
                RECT winrect;
                GetWindowRect(HWND(winId()), &winrect);
                long window_x = winrect.left;
                long window_y = winrect.top;
                const LONG border_width = m_borderWidth;
                if(m_bResizeable)
                        {

                            bool resizeWidth = minimumWidth() != maximumWidth();
                            bool resizeHeight = minimumHeight() != maximumHeight();

                            if(resizeWidth)
                            {
                                //left border
                                if (x >= winrect.left && x < winrect.left + border_width)
                                {
                                    *result = HTLEFT;
                                }
                                //right border
                                if (x < winrect.right && x >= winrect.right - border_width)
                                {
                                    *result = HTRIGHT;
                                }
                            }
                            if(resizeHeight)
                            {
                                //bottom border
                                if (y < winrect.bottom && y >= winrect.bottom - border_width)
                                {
                                    *result = HTBOTTOM;
                                }
                                //top border
                                if (y >= winrect.top && y < winrect.top + border_width)
                                {
                                    *result = HTTOP;
                                }
                            }
                            if(resizeWidth && resizeHeight)
                            {
                                //bottom left corner
                                if (x >= winrect.left && x < winrect.left + border_width &&
                                        y < winrect.bottom && y >= winrect.bottom - border_width)
                                {
                                    *result = HTBOTTOMLEFT;
                                }
                                //bottom right corner
                                if (x < winrect.right && x >= winrect.right - border_width &&
                                        y < winrect.bottom && y >= winrect.bottom - border_width)
                                {
                                    *result = HTBOTTOMRIGHT;
                                }
                                //top left corner
                                if (x >= winrect.left && x < winrect.left + border_width &&
                                        y >= winrect.top && y < winrect.top + border_width)
                                {
                                    *result = HTTOPLEFT;
                                }
                                //top right corner
                                if (x < winrect.right && x >= winrect.right - border_width &&
                                        y >= winrect.top && y < winrect.top + border_width)
                                {
                                    *result = HTTOPRIGHT;
                                }
                            }
                        }
                        if (0!=*result) return true;
                        return false;
            }
    }
    return false;         //此处返回false，留给其他事件处理器处理
}

void BrowserMainWindow::mousePressEvent(QMouseEvent *event)
{
    // event->pos(),鼠标点击的位置，相对于接收事件的窗口坐标
    clickPoint = event->pos();
}

void BrowserMainWindow::mouseMoveEvent(QMouseEvent *event)
{
    // 向量运算
    // pos(), QWidget, 窗口坐标，相对于父窗口，没有父窗口，也就是相对于屏幕
    this->move(event->pos() - clickPoint + pos());
}

void BrowserMainWindow::keyReleaseEvent(QKeyEvent *event)
{
    qDebug() << "键盘监听事件触发" << event->key() << ", " << Qt::Key_Enter << (event->key() == Qt::Key_Enter);
    // f12打开控制台
    if(event->key() == Qt::Key_F12){
        this->ui->content->showConsoleWindow();
    }
//    if(event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return){
//        qDebug() << "回车";
//        const QString url = this->ui->tool_bar->getUrl();
//        this->ui->tab_bar->currentTab->loadUrl(url);
//    }
}


